﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
//using Lmi3d.GoSdk.Messages;
using System.Collections.Concurrent;
using HalconDotNet;
using System.Drawing;
using TPT.Module.BLL;
using MeasureBuilder;
using TPT.Utils;
using System.Collections;
using System.Threading.Tasks;
using NPointToNPointCalibration;
using System.Net.Sockets;
using TPT.Frm;

namespace TPT.Module.Model
{

    #region 窗体动画效果相关常量
    public enum WindowsEffect
    {
        AW_SLIDE = 0x40000,//使用滑动类型。缺省则为滚动动画类型。当使用AW_CENTER标志时，这个标志就被忽略。    
        AW_ACTIVATE = 0x20000,//激活窗口。在使用了AW_HIDE标志后不要使用这个标志。    
        AW_BLEND = 0x80000,//使用淡出效果。只有当hWnd为顶层窗口的时候才可以使用此标志。    
        AW_HIDE = 0x10000,//隐藏窗口，缺省则显示窗口。(关闭窗口用)    
        AW_CENTER = 0x0010,//若使用了AW_HIDE标志，则使窗口向内重叠；若未使用AW_HIDE标志，则使窗口向外扩展。    
        AW_HOR_POSITIVE = 0x0001,//自左向右显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时，该标志将被忽略。    
        AW_VER_POSITIVE = 0x0004,//自顶向下显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时，该标志将被忽略。    
        AW_HOR_NEGATIVE = 0x0002,//自右向左显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时，该标志将被忽略。    
        AW_VER_NEGATIVE = 0x0008//自下向上显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时，该标志将被忽略。    
    }
    #endregion

    #region 登陆模式
    public enum LoginMode
    {
        PRODUCTION_MODE = 0,
        ENGINEERING_MODE = 1,
        CPKGRR_MODE = 2
    }
    public enum UserAuthority
    {
        删除用户 = 0,
        添加用户 = 1,
        设置页查看 = 2,
        查看视觉页,
        编辑点位,
        编辑回零,
        添加项目,
        删除项目,
        编辑参数页
    }
    #endregion

    #region Excel输出格式
    public enum SaveDataFormat
    {
        XLS = 0,
        CSV = 1,
        XLSX = 2
    }
    #endregion

    #region Check模式
    //20180518点检
    public enum CheckMode
    {
        NONE = 0,
        CHECK32 = 32,
        CHECK10 = 10,
        CHECK5 = 5
    }
    #endregion
    public static class Common
    {
        //是否显示软键盘
        public static bool isShowKeyBoard = false;
        //界面运行日志事件
        public static Action<string, Color> AppendUiLog { get; set; }
        //mm延时
        public static void Delay(int milliSeconds)
        {
            if (milliSeconds < 10)
            {
                Thread.Sleep(milliSeconds);
            }
            else
            {
                DateTime tStop = DateTime.Now.AddMilliseconds(milliSeconds);
                while (true)
                {
                    Thread.Sleep(10);
                    if (Application.MessageLoop) Application.DoEvents();

                    if (DateTime.Now > tStop) break;
                }
            }
        }
        //Machine
        public volatile static bool isMachineStandby = false;
        //Motion
        public volatile static UWC300 uwc300;
        public volatile static bool uwc300Initil = false;
        public static int[] uwc300DiStatues = new int[100];
        public static int[] uwc300DoStatues = new int[100];
        public volatile static bool isScanIO = false;
        public static int? deviceStopStatus = null;
        public volatile static bool isPauseScanIO = false;
        public volatile static bool isCardInitialed = false;
        public volatile static int axisTotal = 0;
        public volatile static int actualAxisTotal = 0;
        public const int MAX_DI_CH = 25;
        public const int MAX_DO_CH = 25;
        public volatile static Adlink[] cards = new Adlink[4];
        public volatile static double[] AXIS_PITCH = new double[50];
        public volatile static int totalCardNum = 0;
        public volatile static System.Threading.Timer scanAxisPosition;
        public volatile static List<HomingSetting> axisHomeParams = new List<HomingSetting>();
        //vision
        public volatile static NPointToNPointCalibration.Calibration CameraCalibration;
        public static double GrabImage_X, TakeImage_X;
        public static double GrabImage_Y, TakeImage_Y;
        public volatile static int HalconvisionInitil;
        public volatile static HTuple CameraAcqHandle;
        public static HTuple GocatorAcqHandle;
        public volatile static HTuple CameraName;
        public volatile static Dictionary<string, long> CameraDic = new Dictionary<string, long>();
        public volatile static Dictionary<string, int> CameraDicOrdered = new Dictionary<string, int>();
        public volatile static Dictionary<string, HWindowControl> halconWindow = new Dictionary<string, HWindowControl>();
        public volatile static HWindowControl MotionHalconWindow = new HWindowControl();
        public volatile static bool CameraInitilflag = false;
        public volatile static bool isCameraInitialed = false;
        public volatile static MotionControl motionControl = new MotionControl();
        //Laser
        public volatile static bool isLaserInitSuccess = false;
        public volatile static bool isLaserDone = false;
        public volatile static EventWaitHandle laserDone = new AutoResetEvent(false);
        public static List<LaserModel> lasers = new List<LaserModel>();
        public volatile static Gocator gocator = new Gocator();
        public volatile static KeyenceLineLaserController Keyence7060 = new KeyenceLineLaserController(0);//7060

        public volatile static PointLaser pointLaserTwoHead = new PointLaser("1");
        public volatile static PointLaser pointLaserOneHead = new PointLaser("2");
        public volatile static MscBarcoddata mscdata1 = new MscBarcoddata("192.168.3.1");
        public volatile static MscBarcod mscdata = new MscBarcod();
        public volatile static Client robotSocket = new Client();
        public volatile static Client appleSocket = new Client();
        //public volatile static MiyiPointLaserController LaserController1 = new MiyiPointLaserController();
        //public volatile static MiyiPointLaserController LaserController2 = new MiyiPointLaserController();

        //public volatile static KvEntPlc.PlcClient PLCSocket1;
        public volatile static KeyencePLC PLCRead = new KeyencePLC();
        public volatile static KeyencePLC PLCWrite = new KeyencePLC();
        public volatile static Socket PLCSocket = NetUtils.CreateTcpSocket();

        //初始化指纹锁
        public static BioneFPAPILib.FPAPICtrlClass fp;
        public static string Authority = ""; //登陆用户的权限
        public static string fingerPrintUserName = "";
        public static string fingerPrintAuthority = "";

        //是否屏蔽上工站
        public static bool withoutUpStation = false;
        //需要清料的个数
        public static int howManyProductsNeedClear = 0;

        //machine
        public struct DeviceRunFlag
        {
            public static bool emgStopButton = false;
            public static ManualResetEventSlim stopAll = new ManualResetEventSlim(false);
            public static int ReadEmgStop = 0;
            public static bool[] AxisWarning = new bool[100];
            public static bool[] AxisMel = new bool[100];
            public static bool[] AxisPel = new bool[100];

            public static bool isHomeFinished = false;//回零完成
            public static bool isRunning = false;//正在运行
            public static bool isPaused = false;//暂停中
        }
        public static MachineModel machine = new MachineModel();
        public static IMotionCard[] motionCards = new IMotionCard[4];
        public static List<Light> lightList = new List<Light>();
        public static Light light1 = new Light();
        public static Light light2 = new Light();

        public static Type cardType;
        public volatile static EventWaitHandle station5Done = new AutoResetEvent(false);
        public static EventWaitHandle station5Done1 = new AutoResetEvent(false);
        //path
        public volatile static string pathProgramCfg = FileUtils.GetAppDirectory() + "\\Config\\Program\\";
        public volatile static string pathTepImage = FileUtils.GetAppDirectory() + "\\Config\\TepImage\\";
        public volatile static string pathRegion = FileUtils.GetAppDirectory() + "\\Config\\Region\\";
        //data
        public volatile static string dataSavePath = @"D:\Data\output";
        public volatile static string picSavePath = @"C:\Data\image";

        public volatile static ConcurrentQueue<Battery> WhichBlock = new ConcurrentQueue<Battery>();
        public volatile static ConcurrentQueue<Battery> WhichBlockForGocatorROI = new ConcurrentQueue<Battery>();
        public volatile static ConcurrentQueue<Battery> WhichBlockEnd = new ConcurrentQueue<Battery>();

        public volatile static ConcurrentQueue<Battery> QRQueue = new ConcurrentQueue<Battery>();
        public volatile static ConcurrentQueue<Battery> TurnPanC1MeasureDataQueue = new ConcurrentQueue<Battery>();
        public volatile static ConcurrentQueue<Battery> TurnPanC2MeasureDataQueue = new ConcurrentQueue<Battery>();
        public volatile static ConcurrentQueue<Battery> TurnPanC3MeasureDataQueue = new ConcurrentQueue<Battery>();
        public volatile static ConcurrentQueue<Battery> TurnPanC4MeasureDataQueue = new ConcurrentQueue<Battery>();
        public volatile static ConcurrentQueue<Battery> TurnPanC5MeasureDataQueue = new ConcurrentQueue<Battery>();
        public volatile static ConcurrentQueue<Battery> TurnPanC6MeasureDataQueue = new ConcurrentQueue<Battery>();


        public volatile static ConcurrentQueue<Battery> QRQueue2 = new ConcurrentQueue<Battery>();

        public volatile static ConcurrentQueue<Battery> TurnPanC6MeasureDataNewQueue = new ConcurrentQueue<Battery>();


        public volatile static ConcurrentQueue<Battery> TurnR2GocatorMeasureDataQueue = new ConcurrentQueue<Battery>();
        public volatile static ConcurrentQueue<int> blockNum1 = new ConcurrentQueue<int>();
        public volatile static ConcurrentQueue<int> blockNum2 = new ConcurrentQueue<int>();

        public volatile static List<List<CameraData>> product1CamaraArrayList = new List<List<CameraData>>();
        public volatile static List<List<CameraData>> product2CamaraArrayList = new List<List<CameraData>>();
        public volatile static List<List<CameraData>> product3CamaraArrayList = new List<List<CameraData>>();
        public volatile static List<List<CameraData>> product4CamaraArrayList = new List<List<CameraData>>();
        public volatile static List<List<CameraData>> product5CamaraArrayList = new List<List<CameraData>>();

        public volatile static ConcurrentQueue<List<CameraData>> camaraDataProcessedQueue = new ConcurrentQueue<List<CameraData>>();
        public volatile static ConcurrentQueue<Battery> waitingForWriteToDatabaseDataQueue = new ConcurrentQueue<Battery>();
        public static List<MeasureSize> allMeasureSize = new List<MeasureSize>();
        public static int OKCount = 0;
        public static int NGCount = 0;
        public static int ExceptionCount = 0;
        public static int TotalCount = 0;
        public static int LaserGocatorCount = 0;
        public static int Laser7060Count = 0;
        public static int Count = 0;
        public static bool isRunSpecialProcess = false;
        public static int firstProductPos = 1;
        public static List<string> qrList = new List<string>();
        public static List<int> whichBlockList = new List<int>();
        public static DataSet cpkDataSet = new DataSet();
        public static Task dataThread;

        //Program是否在运行
        public volatile static bool ProgrameAlive = true;
        public static Stopwatch CT = new Stopwatch();
        public static bool? isHaveOne = false;//振动盘取料信号(有料true)
        public static bool? isQiBack = false;
        public static string ProjectName = "";
        public static string startDate = DateTime.Now.ToString("yyyy-MM-dd");
        public static string startTime = DateTime.Now.ToString("HH:mm:ss");

        public static string lastPcsTime = null;//上一片料的保存时间
        public static int clearMachineCount = 0;//清料次数

        //窗体显示情况
        public static bool isSettingFormShow = false;
        public static bool isHomeFormShow = false;
        public static bool isLoginFormshow = false;
        public static bool isParamsSettingDialogShow = false;
        public static bool isStatisticsFromShow = false;
        public static bool isVisionFromshow = false;
        public static bool[] isCameraTabShow = new bool[5];
        public static bool isProjectViewChangeDone = false;
        //login
        public static string username = "";
        public static string password = "";

        //20180518点检
        public volatile static CheckMode SelectCheckMode = CheckMode.NONE;
        public static Int32 CheckNumber = 0;
        public static Int32 CheckStart = 0;
        public volatile static Dictionary<string, double> ValueFromCamera = new Dictionary<string, double>();

        public static OrbitPPG PPG = new OrbitPPG();
        //block
        public static bool isRunBlock = false;
        public static int blockCount = 0;
        //PLC 交互相关信号
        public volatile static bool PLCOnline = false;
        public volatile static bool PCServOn = false;
        public volatile static bool PCPause = false;
        public volatile static bool PLCError = false;
        public volatile static bool PCInit = false;
        public volatile static bool PPG1MoveDone = false;
        public volatile static bool PPG2MoveDone = false;
        public volatile static bool PPG3MoveDone = false;
        public volatile static bool PPG4MoveDone = false;
        public volatile static bool Laser1MoveDone = false;
        public volatile static bool Laser2MoveDone = false;
        public volatile static bool producePutComplete = false;
        public volatile static bool RunWithoutProduct = false;
        public volatile static bool isClearMachine = false;
        public volatile static bool runForType1 = false;
        public volatile static bool isBarcodeClosed = false;
        public volatile static int type1TurnNo = 1;
        public volatile static int cameraDelayTime = 100;
        public volatile static int ppgReadCount = 8;
        public volatile static int PPG1KeepTime = 800;
        public volatile static int PPG2KeepTime = 800;
        public volatile static int PPG3KeepTime = 800;
        public volatile static bool isGocatorProcessOk = false;


        public static bool isC7CatchDone = false;//C7取料完成
        public static bool isAllowR2Turn = false;
        //
        public static int loadNum = 0;//上料次数

        public volatile static bool AxisInitFinished = false;
        public volatile static bool RobotInitFinished = false;
        //各工位程序标志位

        public static bool X1AllowprocessorCCDForTransformGo = false;//上料处让引导CCD只运行一次
        public static bool processorCCDForTransformGo = false;
        public static bool processorR1Circle2Go = false;
        public static bool processorR1Circle3Go = false;
        public static bool processorR1Circle4Go = false;
        public static bool processorR1Circle5Go = false;
        public static bool processorR1Circle6Go = false;

        public static bool processorR2Circle1Go = true;
        public static bool processorR2Circle2Go = false;
        public static bool processorR2Circle3Go = false;
        public static bool processorR2Circle4Go = false;

        //各转盘位是否有料 false表示没有料，true表示有料
        public static bool isSecondLoad = false;
        public static bool isC1Empty = true;
        public static bool isC2Empty = true;
        public static bool isC3Empty = true;
        public static bool isC4Empty = true;
        public static bool isC5Empty = true;
        public static bool isC6Empty = true;
        public static bool isC7Empty = true;
        public static bool isC8Empty = true;
        public static bool isLoadingMove = false;


        public static bool isR2C1Empty = true;
        public static bool isR2C2Empty = true;
        public static bool isR2C3Empty = true;
        public static bool isR2C4Empty = true;


        //进料位有料标志
        public static bool isProductReady = false;
        //Y1取料失败标志
        public static bool isY1Exception = false;
        //机械臂下去抓料时候,让X1线程停止,抓取完毕气缸缩回时候再让X1开始,防止到料信号感应异常
        public static bool isTransformAllowX1Run = true;
        //标志位,禁止流水线信号一直给,
        public static bool isAllowOkRestartAgain = true;
        public static bool isAllowNgRestartAgain = true;

        //public static bool isLineAReleaseDone = false;
        //public static bool isLineBReleaseDone = false;
        //public static bool isLaserAScanDone = false;
        //public static bool isLaserBScanDone = false;

        //public static bool isC3MeasureDone = false;
        //public static bool isC4MeasureDone = false;
        //public static bool isC5MeasureDone = false;
        //public static bool isC6MeasureDone = false;
        public static bool isC1AllowRelease = true;
        public static bool isC7AllowCatch = false;
        public static bool isFirstLoad = true;

        //当前转盘号
        public static int R1currentTurnPanNo = 1;
        public static int R2currentTurnPanNo = 1;
        public static bool isOKEmpty = true;
        //连接信号灯
        public static bool RobotConnect = false;
        public static bool PLCConnect = false;
        public static bool BarcodeAConnect = false;
        public static bool BarcodeBConnect = false;
        public static int isMachineAllInit = 0;

        public static bool isForceRobotGo = false;

        public static HTuple FAI6RowBegin2 = 0;
        public static HTuple FAI6ColBegin2 = 0;
        public static HTuple FAI6RowEnd2 = 0;
        public static HTuple FAI6ColEnd2 = 0;
        public static HTuple FAI1RowBegin2 = 0;
        public static HTuple FAI1ColBegin2 = 0;
        public static HTuple FAI1RowEnd2 = 0;
        public static HTuple FAI1ColEnd2 = 0;
        public static HTuple FAI98RowBegin2 = 0;
        public static HTuple FAI98ColBegin2 = 0;
        public static HTuple FAI98RowEnd2 = 0;
        public static HTuple FAI98ColEnd2 = 0;
        public static HTuple FAI20RowBegin2 = 0;
        public static HTuple FAI20ColBegin2 = 0;
        public static HTuple FAI20RowEnd2 = 0;
        public static HTuple FAI20ColEnd2 = 0;

        public static HTuple dFai_2 = 0;
        public static HTuple DFai_2 = 0;
        public static HTuple dFai_96 = 0;
        public static HTuple dFai_96_2 = 0;
        public static HTuple dFai_96_3 = 0;
        public static HTuple dFai_96_4 = 0;
        public static HTuple dFai_96_5 = 0;
        public static HTuple dFai_96_6 = 0;
        public static HTuple DFai_96 = 0;
        public static HTuple DFai_96_2 = 0;
        public static HTuple DFai_96_3 = 0;
        public static HTuple DFai_96_4 = 0;
        public static HTuple DFai_96_5 = 0;
        public static HTuple DFai_96_6 = 0;
        public static HTuple dFai_20 = 0;
        public static HTuple DFai_20 = 0;

        public static double FAI103Value;
        public static double FAI102Value;
        //PPG转盘各个工位补偿值
        //PPG1
        public static double PPG1C1 = 0;
        public static double PPG1C2 = 0;
        public static double PPG1C3 = 0;
        public static double PPG1C4 = 0;
        public static double PPG1C5 = 0;
        public static double PPG1C6 = 0;
        public static double PPG1C7 = 0;
        public static double PPG1C8 = 0;
        //PPG2
        public static double PPG2C1 = 0;
        public static double PPG2C2 = 0;
        public static double PPG2C3 = 0;
        public static double PPG2C4 = 0;
        public static double PPG2C5 = 0;
        public static double PPG2C6 = 0;
        public static double PPG2C7 = 0;
        public static double PPG2C8 = 0;
        //PPG3
        public static double PPG3C1 = 0;
        public static double PPG3C2 = 0;
        public static double PPG3C3 = 0;
        public static double PPG3C4 = 0;
        public static double PPG3C5 = 0;
        public static double PPG3C6 = 0;
        public static double PPG3C7 = 0;
        public static double PPG3C8 = 0;
        //Keyence7060
        public static double BaseSurfaceC1 = 0;
        public static double BaseSurfaceC2 = 0;
        public static double BaseSurfaceC3 = 0;
        public static double BaseSurfaceC4 = 0;
        public static double BaseSurfaceC5 = 0;
        public static double BaseSurfaceC6 = 0;
        public static double BaseSurfaceC7 = 0;
        public static double BaseSurfaceC8 = 0;

        public static double ReferenceBlock_1 = 0;
        public static double ReferenceBlock_2 = 0;
        public static double ReferenceBlock_3 = 0;
        public static double ReferenceBlock_4 = 0;
        //X轴取料运动步长
        public static double X1AbsDistance = 0;
        public static double X1StartPosition = 0;
        public static int X1RunNumber = 0;
        //数据保存
        public volatile static bool isSaveLaserCsv = false;
        //点检
        public static bool isAutoCompensation = false;//是否自动补偿
        public static string pointCheckPath = @"D:\Data\Config";
        public static string pointCheckPath1 = @"D:\Data\Config";
        public static bool isPointCheck = false;//Block点检标志
        public static bool isGRRPointCheck = false;//GRR点检标志
        public static bool isLinearPointCheck = false;//线性点检标志 默认开启 真实测block数据关闭
        //bottom
        public static string GRRPointCheckSize_Bottom = "";//GRR点检尺寸
        public static DataTable pointCheckTable_Bottom = null;//Block点检表
        public static DataTable GRRPointCheckTable_Bottom = null;//GRR点检表
        public static DataTable GRRRangeTable_Bottom = null;//GRR范围表
        public static DataTable LinearRangeTable_Bottom = null;//Linear范围表
        public static DataTable BlockNomalTable_Bottom = null;//Block标准值
        //book
        public static string GRRPointCheckSize_Book = "";//GRR点检尺寸
        public static DataTable pointCheckTable_Book = null;//Block点检表
        public static DataTable GRRPointCheckTable_Book = null;//GRR点检表
        public static DataTable GRRRangeTable_Book = null;//GRR范围表
        public static DataTable LinearRangeTable_Book = null;//Linear范围表
        public static DataTable BlockNomalTable_Book = null;//Block标准值



        //post book
        public static string GRRPointCheckSize_PostBook = "";//GRR点检尺寸
        public static DataTable pointCheckTable_PostBook = null;//Block点检表
        public static DataTable GRRPointCheckTable_PostBook = null;//GRR点检表
        public static DataTable GRRRangeTable_PostBook = null;//GRR范围表
        public static DataTable LinearRangeTable_PostBook = null;//Linear范围表
        public static DataTable BlockNomalTable_PostBook = null;//Block标准值


        //PostBottom
        public static string GRRPointCheckSize_PostBottom = "";//GRR点检尺寸
        public static DataTable pointCheckTable_PostBottom = null;//Block点检表
        public static DataTable GRRPointCheckTable_PostBottom = null;//GRR点检表
        public static DataTable GRRRangeTable_PostBottom = null;//GRR范围表
        public static DataTable LinearRangeTable_PostBottom = null;//Linear范围表
        public static DataTable BlockNomalTable_PostBottom = null;//Block标准值


        //两个R轴放料间隔
        public static double internalTime = 0.0;
        public static Stopwatch internalTimeStopwatch = new Stopwatch();
        //算子所在路径
        public static string ProcedurePath = "";

        //book bottom切换程序参数
        public static bool isNeedPause = false;
        public static string currentProject = "";

        // 判断是否有Gocator
        public static bool isHaveGocator = true;

        public static double dFAI10 = 0;
        //上传Mes
        public static string MesJession = "";
        public static string MesTestId = "";
        public static string MesUrl = "";
        public static bool isUploadMes = false;
        public static bool isUploadApple = false;
        public static string MesDcGroup = "";
        public static bool UploadMESFail = false; //上传MES失败

        public static bool isClickOk2 = false; //
        //线别
        public static string Line = ""; //

        //是否文件夹已经加密，默认是加密状态
        public static bool isFileSetPassCode = true;

        public struct FPUserInfo
        {
            public static string UserName;   //用户名
        }

        public volatile static ROIComapreForm roiCompareForm = null;
        public static FignerPrintForm FPForm = new FignerPrintForm();

        public static bool b_FPLoginClick = false;

        public static bool b_ModifyROIButtonClick = false;

        public static bool b_SaveROIButtonClick = false;

        public volatile static Frm_Home homeForm = null;
        public volatile static Frm_Setting settingForm = null;
        public volatile static Frm_Vision visionFrom = null;
        public volatile static Frm_Login loginForm = null;

    }

    public class GUIEventArgs : EventArgs
    {
        public int Index { get; set; }

        public GUIEventArgs(int msg)
        {
            Index = msg;
        }
    }
}
